#
# Ronin Exploits - A Ruby library for Ronin that provides exploitation and
# payload crafting functionality.
#
# Copyright (c) 2007-2013 Hal Brodigan (postmodern.mod3 at gmail.com)
#
# This file is part of Ronin Exploits.
#
# Ronin is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ronin is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ronin.  If not, see <http://www.gnu.org/licenses/>
#

require 'ronin/ui/cli/script_command'
require 'ronin/exploits'
require 'ronin/payloads'
require 'ronin/database'

module Ronin
  module UI
    module CLI
      module Commands
        class Exploit < ScriptCommand

          summary 'Builds and deploys an exploit'

          script_class Ronin::Exploits::Exploit

          # exploit options
          option :dry_run, type: true
          option :raw_payload, type: String

          # target options
          option :target, type: Integer, flag: '-t'
          option :target_arch, type: String, flag: '-a'
          option :target_os, type: String, flag: '-o'
          option :target_software, type: String
          option :target_version, type: String

          # payload options
          option :payload, type: String,
                           flag: '-P'
          option :payload_file, type: String

          # post-exploit options
          option :shell, type: true
          option :fs, type: true

          #
          # Builds and deploys the loaded exploit.
          #
          def execute
            begin
              @exploit.exploit!(dry_run: dry_run?)
            rescue Behaviors::Exception,
                   Exploits::Exception,
                   Payloads::Exception => e
              print_exception(e)
              exit -1
            end

            if shell?      then @exploit.shell.console
            elsif fs?      then @exploit.fs.console
            elsif console? then UI::Console.start(@exploit)
            end

            @exploit.evaucate!
          end

          protected

          #
          # Loads the Exploit, selects the desired Target, and loads the
          # additional Payload.
          #
          def load!
            @exploit = super

            @exploit.use_target!(
              arch:     @target_arch,
              os:       @target_os,
              software: [@target_software, @target_version]
            )

            if raw_payload?
              @exploit.raw_payload = @raw_payload
            elsif payload_file?
              @exploit.use_payload_from!(@payload_file)
            elsif payload_name?
              @exploit.use_payload(name: @payload)
            end

            unless @exploit.payload
              print_error "Could not find a compatible payload for the exploit!"
              exit -1
            end

            return @exploit
          end

          #
          # Parses additional options for the loaded Exploit and Payload.
          #
          def param_option_parser
            super do |opts|
              if @exploit.payload
                opts.separator ''
                opts.separator 'Payload Options:'

                @exploit.payload.each_param do |param|
                  Parameters::Options.define(opts,param)
                end
              end
            end
          end

        end
      end
    end
  end
end
